home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_09_02 / 9n02138a < prev    next >
Text File  |  1990-12-28  |  7KB  |  217 lines

  1. /***********************************************
  2. *   MDEDIT.C                                   *
  3. *                                              *
  4. *   Program:        Mini-Database              *
  5. *   Written by:     Leor Zolman                *
  6. *   Module:         Edit the Current Database  *
  7. ************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include "mdb.h"
  14.  
  15. static void fix_db(void);
  16.  
  17. #define LIST_RECS   1    /* Edit menu action codes */
  18. #define NEXT        2
  19. #define PREVIOUS    3
  20. #define MODIFY      4
  21. #define NEW         5
  22. #define DELETE      6
  23. #define UNDELETE    7
  24. #define QUIT        8
  25. #define SELECT      9
  26. #define FIX        10
  27.  
  28. static struct menu_item edit_menu[] = {
  29.     {LIST_RECS, "List Records"},
  30.     {NEXT, "Go to Next Record"},
  31.     {PREVIOUS, "Go to Previous Record"},
  32.     {MODIFY, "Modify Current Record"},
  33.     {NEW, "Add New Record"},
  34.     {DELETE, "Delete Current Record"},
  35.     {UNDELETE, "Un-Delete Current Record"},
  36.     {SELECT, "Select Record (by Record Number)"},
  37.     {FIX, "Fix Up Database"},
  38.     {QUIT, "Return to Main Menu"},
  39.     {'\0'}
  40. };
  41.  
  42. /**************************************************
  43.  * Function:        edit_db
  44.  * Purpose:         Perform operations on current 
  45.                       Database
  46.  * Parameter:       Database Name
  47.  * Return Value:    None
  48.  */
  49.  
  50. void edit_db(char *db_name) {
  51.   int     cur_rec = 0; /* current record number */
  52.   struct  record *rp;
  53.   char    buf[150];
  54.   int     i;
  55.  
  56.   while (1) {
  57.      rp = RECS[cur_rec];
  58.      printf("\nDatabase: %s\n", db_name);
  59.      if (n_recs)
  60.      {
  61.         printf("Current Record is #%d", cur_rec);
  62.         if (!rp->active)
  63.              printf(" (Deleted)");
  64.         printf(":\n");
  65.  
  66.         printf("Name:   %s %s\n", rp->first, rp->last);
  67.         printf("ID#:    %ld\n", rp->id);
  68.         printf("Age:    %d\n", rp->age);
  69.         printf("Gender: %c\n", rp->gender);
  70.         printf("Salary: $%.2f\n", rp->salary);
  71.       }
  72.  
  73.       switch(do_menu(edit_menu, "Edit Menu")) {
  74.  
  75.           case LIST_RECS:
  76.             for(i = 0; i < n_recs; i++)
  77.                  printf("%4d: %s%s\n", i, RECS[i]->last,
  78.                     RECS[i]->active ? "" : " (Deleted)");
  79.             printf("Press RETURN to continue:");
  80.             gets(buf);
  81.             break;
  82.           case NEXT:         /* find next active record: */
  83.             for (i = cur_rec + 1; i < n_recs; i++)
  84.                 if (RECS[i]->active)  /* skip inactives  */
  85.                     break;
  86.             if (i == n_recs) {  /* over the top?  */
  87.                  printf("\aAt end of file.\n");
  88.                  break;
  89.               }
  90.             cur_rec = i;
  91.             break;
  92.           case PREVIOUS:   /* find previous active record: */
  93.               for (i = cur_rec - 1; i >= 0; i--)
  94.                  if (RECS[i]->active)    /* skip inactives  */
  95.                      break;
  96.               if (i < 0) {    /* "under the bottom"?  */
  97.                   printf("\aAt beginning of file.\n");
  98.                   break;
  99.               }
  100.               cur_rec = i;
  101.               break;
  102.           case NEW:
  103.               if (n_recs+1 > max_recs) {
  104.                   printf("Maximum # of records ");
  105.                   printf("(%d) reached.\n", max_recs);
  106.                   break;
  107.                }
  108.                if ((rp = alloc_rec()) == NULL) {
  109.                   printf("Out of memory. Try Fixing ");
  110.                   printf("Database first...\n");
  111.                   break;
  112.                }
  113.                           /* make new record current: */
  114.                cur_rec = n_recs++;
  115.                RECS[cur_rec] = rp;
  116.                rp->active = TRUE;
  117.                strcpy(rp->last,""); /* initialize the record  */
  118.                strcpy(rp->first,"");
  119.                rp->id = 0;
  120.                rp->age = 0;
  121.                rp->gender = ' ';
  122.                rp->salary = 0.0F;  /* fall through to MODIFY */
  123.           case MODIFY:
  124.               printf("Last Name [%s]: ", rp->last);
  125.               if (strlen(gets(buf)) > 0)
  126.                   strcpy(rp->last, buf);
  127.               printf("First Name [%s]: ", rp->first);
  128.               if (strlen(gets(buf)) > 0)
  129.                   strcpy(rp->first, buf);
  130.               printf("ID# [%ld]: ", rp->id);
  131.               if (strlen(gets(buf)) > 0)
  132.                   rp->id = atol(buf);
  133.               printf("Age [%d] ", rp->age);
  134.               if (strlen(gets(buf)) > 0)
  135.                   rp->age = atoi(buf);
  136.               printf("Gender [%c]: ", rp->gender);
  137.               if (strlen(gets(buf)) > 0)
  138.                   rp->gender = (char)toupper(*buf);
  139.               printf("Salary [%.2f]: ", rp->salary);
  140.               if (strlen(gets(buf)) > 0)
  141.                   rp->salary = (float) atof(buf);
  142.               break;
  143.           case DELETE:
  144.               if (!rp->active) {
  145.                  printf("Record is already deleted.\n");
  146.                  break;
  147.               }
  148.               printf("Press 'y' to delete record,\n");
  149.               printf("anything else to abort: ");
  150.               gets(buf);
  151.               if (tolower(*buf) == 'y')
  152.                   rp->active = FALSE;
  153.               break;
  154.           case UNDELETE:
  155.               if (rp->active) {
  156.                  printf("Record is not deleted.\n");
  157.                  break;
  158.               }
  159.               rp->active = TRUE;
  160.               printf("Record restored.\n");
  161.               break;
  162.           case SELECT:
  163.               printf("Enter new record number: ");
  164.               i = atoi(gets(buf));
  165.               if (i < 0 || i > n_recs) {
  166.                 printf("Record # out of range.\n");
  167.                 break;
  168.               }
  169.               cur_rec = i;
  170.               break;
  171.           case FIX:
  172.               fix_db();    /* clean up database  */
  173.               break;
  174.           case QUIT:
  175.               return;
  176.       }
  177.    }
  178. }
  179.  
  180. /**************************************************
  181.  *
  182.  * Function:        fix_db
  183.  * Purpose:         Purge deleted records, sort db
  184.  * Parameters:      None
  185.  * Return Value:    None
  186.  */
  187.  
  188. static int compar(const void *a, const void *b);
  189.  
  190. static void fix_db(void) {     /* File Fix module */
  191.     int i, new_n_recs;
  192.  
  193.     for (i = 0, new_n_recs = 0; i < n_recs; i++) {
  194.         RECS[new_n_recs] = RECS[i];
  195.         if (RECS[i]->active)
  196.             new_n_recs++;
  197.         else
  198.             free(RECS[i]);
  199.     }
  200.     n_recs = new_n_recs;
  201.     qsort(RECS, new_n_recs, sizeof(struct record *), compar);
  202. }
  203.  
  204. /**************************************************
  205.  * Function:        compar
  206.  * Purpose:         Comparison function for qsort(),
  207.  *                    sorting simply on last name
  208.  * Parameters:      Two pointers to record pointers
  209.  * Return Value:    As per strcmp()
  210.  */
  211.  
  212. static int compar(const void *a, const void *b) {
  213.     struct record **p1 = (struct record **)a;
  214.     struct record **p2 = (struct record **)b;
  215.     return strcmp((*p1)->last, (*p2)->last);
  216. }
  217.